package com.whcoding.test.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.whcoding.test.common.CollectionUtils;
import com.whcoding.test.constant.BaseConstant;
import com.whcoding.test.dao.VehicleTrackDetailDao;
import com.whcoding.test.dao.VehicleTrackMainDao;
import com.whcoding.test.dao.VehicleTrackParkDetailDao;
import com.whcoding.test.example.crt.*;
import com.whcoding.test.example.crt.po.VehicleTrackDetailPO;
import com.whcoding.test.example.crt.po.VehicleTrackMainPO;
import com.whcoding.test.example.crt.po.VehicleTrackParkDetailPO;
import com.whcoding.test.service.CrtVehicleTrackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class CrtVehicleTrackServiceImpl implements CrtVehicleTrackService {

    /**
     * 车辆轨迹主表
     */
    @Autowired
    VehicleTrackMainDao vehicleTrackMainDao;

    /**
     * 车辆轨迹明细
     */
    @Autowired
    VehicleTrackDetailDao vehicleTrackDetailDao;


    /**
     * 车辆轨迹停车表
     */
    @Autowired
    VehicleTrackParkDetailDao vehicleTrackParkDetailDao;


    /**
     * 测试API 请求
     */
    private void tempApiTest(){
        VendorWayCodeVehicleTrackVO vehicleTrackVO= new VendorWayCodeVehicleTrackVO();
        DateTime dateTime = new DateTime("2023-04-13 00:10:00", DatePattern.NORM_DATETIME_FORMAT);
        vehicleTrackVO.setCtnrNum("TBGU5346650");
        vehicleTrackVO.setVendorWaybillCode("GY230418000001");
        vehicleTrackVO.setVehicleNo("桂N83139");
        vehicleTrackVO.setVendorWaybillBeginTime(dateTime);
        vehicleTrackVO.setVehicleColor(2);
        vehicleTrackVO.setVehicleId(2);
        vehicleTrackVO.setWid("20230424_1002");

        for (int i = 0; i < 3; i++) {
            System.out.println("第"+i+":次请求前的参数为:"+ JSONObject.toJSONString(vehicleTrackVO));
            VendorWayCodeVehicleTrackVO vehicleTrackVO2= getApiParam2(vehicleTrackVO);
            System.out.println("第"+i+":次请求后的参数为:"+ JSONObject.toJSONString(vehicleTrackVO2));
        }
    }


    /**
     *
     * @param paramVO 参数 开始时间
     * @return
     */
    private VendorWayCodeVehicleTrackVO getApiParam2(VendorWayCodeVehicleTrackVO paramVO){
        //数据库中上传执行的时间
        VehicleTrackMainPO maxEndMainPO=vehicleTrackMainDao.findByVehicleIdAndVendorWaybillCodeAndDeleted(paramVO.getVehicleId(), paramVO.getVendorWaybillCode(), 0);

        Date maxDbEndTime=null;
        //数据库中的开始时间
        Date maxDbBeginTime=null;
        if (Objects.nonNull(maxEndMainPO)){
            maxDbEndTime=maxEndMainPO.getVendorWaybillEndTime();
            maxDbBeginTime=maxEndMainPO.getVendorWaybillBeginTime();
        }

        Date nowDate= new Date();
        Date beginTime= paramVO.getVendorWaybillBeginTime();
        Date endTime= paramVO.getVendorWaybillEndTime();
        //任务已完成(开始时间=任务结束时间,结束时间=当前时间)
        if (Objects.nonNull(endTime)){
            paramVO.setVendorWaybillBeginTime(Objects.isNull(maxDbEndTime)?endTime:maxDbEndTime);
            paramVO.setVendorWaybillEndTime(nowDate);
            paramVO.setDealStatus(1);
        }else {
            //判断数据库中是否已经执行了 、若已经执行了  则取上次执行的截止时间
            //任务未结束(开始时间=开始时间,结束时间=当前时间)
            paramVO.setVendorWaybillBeginTime(Objects.isNull(maxDbEndTime)?beginTime:maxDbEndTime);
            paramVO.setVendorWaybillEndTime(nowDate);
        }



        if (Objects.nonNull(maxDbBeginTime)){
            //系统的最早处理时间和当前时间相差72小时 则不处理
            Long diffHour = DateUtil.between(maxDbBeginTime, nowDate, DateUnit.HOUR);
//            long diffHour2= DateTimeUtil.dateDiffHours(maxEndMainPO.getVendorWaybillBeginTime(),nowDate);
            if (diffHour>72){
                System.out.println("相差时间大于7小时");
                paramVO.setDealStatus(2);
            }
        }

        //保存到数据库中
        saveToDB(paramVO);
        System.out.println("保存数据库执行完成!");
        return paramVO;
    }

    /**
     * 保存到数据库中
     */
    private void saveToDB(VendorWayCodeVehicleTrackVO paramVO){
        VehicleTrackMainPO vehicleTrackMainPO  = vehicleTrackMainDao.findByVehicleIdAndVendorWaybillCodeAndDeleted(paramVO.getVehicleId(), paramVO.getVendorWaybillCode(),0);
        if (Objects.isNull(vehicleTrackMainPO)){
            vehicleTrackMainPO = new VehicleTrackMainPO();
            vehicleTrackMainPO.setCreateAt(new Date());
        }

        Date beginTime= Objects.isNull(vehicleTrackMainPO.getVendorWaybillBeginTime())?paramVO.getVendorWaybillBeginTime():vehicleTrackMainPO.getVendorWaybillBeginTime();
        Integer disposeNum= Objects.isNull(vehicleTrackMainPO.getDisposeNum())?0:vehicleTrackMainPO.getDisposeNum();

        //查询参数
        vehicleTrackMainPO.setVehicleId(paramVO.getVehicleId());
        vehicleTrackMainPO.setVehicleNo(paramVO.getVehicleNo());
        vehicleTrackMainPO.setVendorWaybillCode(paramVO.getVendorWaybillCode());
        vehicleTrackMainPO.setVendorWaybillBeginTime(beginTime);
        vehicleTrackMainPO.setVendorWaybillEndTime(paramVO.getVendorWaybillEndTime());
        //接口返回数据
        vehicleTrackMainPO.setMileage(BigDecimal.ONE);
        vehicleTrackMainPO.setParkSize(10);
        vehicleTrackMainPO.setStatus(paramVO.getStatus());
        //若接口返回失败
        if (!Integer.valueOf(1001).equals(paramVO.getStatus())){
            System.out.println(disposeNum+1);
            vehicleTrackMainPO.setDisposeNum(disposeNum+1);
        }
        //处理状态
        vehicleTrackMainPO.setDisposeStatus(0);
        vehicleTrackMainPO.setDeleted(0);
        //保存主表数据
        VehicleTrackMainPO resultPO = vehicleTrackMainDao.save(vehicleTrackMainPO);
    }




    /**
     * 保存车辆轨迹数据
     */
    @Override
    public void saveVehicleTrack() {

        tempApiTest();
        System.out.println("测试API");
        //2.保存主表数据
        VehicleTrackMainPO vehicleTrackMainParmPO = new VehicleTrackMainPO();

        List<VehicleTrackMainPO>  aaList= vehicleTrackMainDao.findAllByVehicleIdAndVendorWaybillCodeAndDeleted(11,"CODE_20230421",0);

        VehicleTrackMainPO trackMainPO=vehicleTrackMainDao.findByVehicleIdAndVendorWaybillCodeAndDeleted(11,"CODE_20230421",10);
        if (Objects.isNull(trackMainPO)){
            trackMainPO=new VehicleTrackMainPO();
        }
        trackMainPO.setVehicleId(15);
        trackMainPO.setVehicleNo("1233");
        trackMainPO.setVendorWaybillCode("CODE_21");
        trackMainPO.setDisposeNum(1);
        vehicleTrackMainDao.save(trackMainPO);

        VehicleTrackMainPO testPo = aaList.get(0);

        testPo.setVehicleId(12);
        testPo.setVehicleNo("123");
        testPo.setVendorWaybillCode("CODE_20");
        testPo.setDisposeNum(1);
        vehicleTrackMainDao.save(testPo);

        VehicleTrackMainPO tempPo= aaList.get(0);
        System.out.println(tempPo);
        tempPo.setVehicleTrackMainId(5);
        vehicleTrackMainDao.save(tempPo);


        VehicleTrackMainPO mainPO= saveVehicleTrackMain(vehicleTrackMainParmPO);

        ResultVO resultVO = new ResultVO();

        if (Objects.nonNull(resultVO.getResult())) {

            //1.检查数据是否需要进行保存
            isPass(resultVO.getResult());


            if (Objects.nonNull(mainPO)&&mainPO.getVehicleTrackMainId()>0){

                //3.保存停车数据
                saveVehicleTrackParkDetail(mainPO.getVehicleTrackMainId());

                //4.保存轨迹数据
                saveVehicleTrackDetail(mainPO.getVehicleTrackMainId());
            }


            /**
             * 主表数据
             */
            ResultVehicleTrackVO resultVehicleTrackVO = resultVO.getResult();

            //轨迹数据
            List<VehicleTrackVO> trackVOS = resultVehicleTrackVO.getTrackArray();

            //停车数据
            List<VehicleTrackParkVO> parkVOS = resultVehicleTrackVO.getParkArray();

        }
    }


    /**
     * 1. 保存主表数据
     * <p>
     * 一个运单是否会存在多个车辆 多条轨迹
     * <p>
     * TODO :运单+车辆是否可以确定唯一数据
     */
    private VehicleTrackMainPO saveVehicleTrackMain(VehicleTrackMainPO vehicleTrackMainPO) {
        vehicleTrackMainPO.setVehicleTrackMainId(1);
        //查询参数
        vehicleTrackMainPO.setVehicleId(0);
        vehicleTrackMainPO.setVehicleNo("陕A12345");
        vehicleTrackMainPO.setVendorWaybillCode("CODE_20230421");
        DateTime bTime = new DateTime("2023-01-05 12:00:00", DatePattern.NORM_DATETIME_FORMAT);
        DateTime eTime = new DateTime("2023-01-05 12:30:23", DatePattern.NORM_DATETIME_FORMAT);
        vehicleTrackMainPO.setVendorWaybillBeginTime(bTime);
        vehicleTrackMainPO.setVendorWaybillEndTime(eTime);

        //接口返回数据
        vehicleTrackMainPO.setMileage(new BigDecimal("2.36"));
        vehicleTrackMainPO.setParkSize(10);
        //处理状态
        vehicleTrackMainPO.setStatus(1001);
        vehicleTrackMainPO.setDisposeNum(0);
        vehicleTrackMainPO.setDisposeStatus(0);
        vehicleTrackMainPO.setDeleted(0);
//        vehicleTrackMainPO.setCreateAt(new Date());
        //保存主表数据
        VehicleTrackMainPO resultPO = vehicleTrackMainDao.save(vehicleTrackMainPO);
        return resultPO;
    }


    /**
     * 2. 保存停车明细
     */
    private void saveVehicleTrackParkDetail(Integer vehicleTrackMainId) {

        VehicleTrackParkDetailPO vehicleTrackParkDetailPO = new VehicleTrackParkDetailPO();
        List<VehicleTrackParkDetailPO> vehicleTrackParkDetailPOS = new ArrayList<>(16);

        //保存停车明细数据
        if (CollectionUtils.isNotEmpty(vehicleTrackParkDetailPOS)) {

            for (VehicleTrackParkDetailPO trackParkDetailPO : vehicleTrackParkDetailPOS) {
                trackParkDetailPO.setVehicleTrackMainId(vehicleTrackMainId);
                trackParkDetailPO.setDeleted(BaseConstant.DEFAULT_VALID_ZERO);
                trackParkDetailPO.setCreateAt(new Date());
            }
            vehicleTrackParkDetailDao.saveAll(vehicleTrackParkDetailPOS);
        }

    }


    /**
     * 3. 保存车辆轨迹明细
     */
    private void saveVehicleTrackDetail(Integer vehicleTrackMainId) {

        List<VehicleTrackDetailPO> vehicleTrackDetailPOS = new ArrayList<>(16);
        //保存轨迹数据
        if (CollectionUtils.isNotEmpty(vehicleTrackDetailPOS)) {
            for (VehicleTrackDetailPO trackDetailPO : vehicleTrackDetailPOS) {
                trackDetailPO.setVehicleTrackMainId(vehicleTrackMainId);
                trackDetailPO.setDeleted(BaseConstant.DEFAULT_VALID_ZERO);
                trackDetailPO.setCreateAt(new Date());
            }
            vehicleTrackDetailDao.saveAll(vehicleTrackDetailPOS);
        }

    }


    /**
     * 数据是否通过
     *
     * @param resultVO
     * @return
     */
    private boolean isPass(ResultVehicleTrackVO resultVO) {
        Integer vehicleId = 0;
        String vendorWaybillCode = "";
        VehicleTrackMainPO existMainPo = vehicleTrackMainDao.findByVehicleIdAndVendorWaybillCodeAndDeleted(vehicleId, vendorWaybillCode, BaseConstant.DEFAULT_VALID_ZERO);
        //数据未处理
        if (Objects.nonNull(existMainPo) && existMainPo.getVehicleTrackMainId() > 0 && existMainPo.getDisposeStatus().equals(0)) {
            //状态未成功,且处理次数小于3次
            if (!resultVO.getStatus().equals(Integer.valueOf(1001))) {
                existMainPo.setDisposeNum(existMainPo.getDisposeNum() + 1);

                //处理次数大于3次则标记为已处理
                existMainPo.setDisposeStatus(existMainPo.getDisposeNum() > 3 ? 1 : 0);
                vehicleTrackMainDao.save(existMainPo);

                //数据状态为已处理则返回
                if (existMainPo.getDisposeStatus().equals(1)) {
                    return false;
                }
            }

        }
        return true;
    }
}
